/**
 * @file 地图容器钩子
 * @description 封装百度地图容器核心逻辑与功能，提供声明式API实现地图实例管理
 * @module hooks/map/useMapContainer
 * @date 2024-06-28
 * @author GPS项目团队
 * 
 * @description 功能概述:
 * - 创建和管理百度地图实例
 * - 提供地图初始化、配置与销毁的完整生命周期管理
 * - 处理地图控件添加和自定义
 * - 处理地图事件监听与清理
 * - 提供地图操作接口(中心点、缩放、视图范围等)
 * - 维护地图状态并与全局store同步
 * 
 * @requires Vue
 * @requires @/config/map.config
 * @requires @/stores/modules/map
 * @requires @/utils/system/logger
 * 
 * @example
 * // 基本使用方式
 * const {
 *   map,
 *   loading,
 *   error,
 *   initialized,
 *   initMap,
 *   setCenter,
 *   setZoom
 * } = useMapContainer({
 *   containerId: 'map-container',
 *   center: { lng: 116.404, lat: 39.915 },
 *   zoom: 12
 * });
 */
// @ts-ignore - uni-app环境下Vue导入需要忽略类型检查
import { ref, reactive, onMounted, onUnmounted, watch } from 'vue';
import { BAIDU_MAP_CONFIG } from '@/config/map.config';
import { useMapStore } from '@/stores/modules/map';
import { logger } from '@/utils/system/logger';

// 类型定义
export interface MapPoint {
  lng: number;
  lat: number;
}

export interface MapContainerOptions {
  center?: MapPoint;
  zoom?: number;
  containerId?: string;
  showBuildings?: boolean;
  mapType?: string;
  showControls?: boolean;
  showScaleControl?: boolean;
  showZoomControl?: boolean;
  showMapTypeControl?: boolean;
  showLocationControl?: boolean;
  showCityListControl?: boolean;
  show3DControl?: boolean;
  lazyLoad?: boolean;
  
  // 事件回调
  onReady?: (map: any) => void;
  onClick?: (e: any) => void;
  onMoveEnd?: (e: any) => void;
  onReset?: () => void;
}

/**
 * 地图容器钩子
 * @param options 地图容器配置项
 */
export function useMapContainer(options: MapContainerOptions = {}) {
  // 合并默认配置
  const opts = {
    center: options.center || BAIDU_MAP_CONFIG.defaultCenter,
    zoom: options.zoom || BAIDU_MAP_CONFIG.defaultOptions.zoom,
    containerId: options.containerId || 'bmap-container',
    showBuildings: options.showBuildings !== undefined ? options.showBuildings : true,
    mapType: options.mapType || 'normal',
    showControls: options.showControls !== undefined ? options.showControls : true,
    showScaleControl: options.showScaleControl !== undefined ? options.showScaleControl : true,
    showZoomControl: options.showZoomControl !== undefined ? options.showZoomControl : true,
    showMapTypeControl: options.showMapTypeControl !== undefined ? options.showMapTypeControl : true,
    showLocationControl: options.showLocationControl !== undefined ? options.showLocationControl : false,
    showCityListControl: options.showCityListControl !== undefined ? options.showCityListControl : false,
    show3DControl: options.show3DControl !== undefined ? options.show3DControl : true,
    lazyLoad: options.lazyLoad !== undefined ? options.lazyLoad : false,
    
    // 事件回调
    onReady: options.onReady || null,
    onClick: options.onClick || null,
    onMoveEnd: options.onMoveEnd || null,
    onReset: options.onReset || null
  };
  
  // 响应式状态
  const mapContainerRef = ref<HTMLDivElement | null>(null);
  const map = ref<any>(null);
  const trackPluginLoaded = ref(false);
  const initialized = ref(false);
  const loading = ref(false);
  const error = ref<string | null>(null);
  
  // 使用地图Store
  const mapStore = useMapStore();
  
  // 事件监听器和控件缓存
  const eventListeners = new Map<string, any>();
  const controls = new Map<string, any>();
  
  /**
   * 初始化地图
   */
  async function initMap(): Promise<boolean> {
    if (!mapContainerRef.value) {
      logger.error('地图容器不存在');
      error.value = '地图容器不存在';
      return false;
    }
    
    // 如果已经初始化，则跳过
    if (initialized.value && map.value) {
      return true;
    }
    
    loading.value = true;
    error.value = null;
    
    try {
      // 确保地图资源已加载
      if (!mapStore.isMapReady) {
        const loadSuccess = await mapStore.loadMapOnDemand();
        if (!loadSuccess) {
          throw new Error('地图资源加载失败');
        }
      }
      
      // 检查轨迹插件状态
      trackPluginLoaded.value = mapStore.capabilities.trackPluginLoaded;
      
      // 创建地图实例
      map.value = new window.BMapGL.Map(opts.containerId, {
        enableMapClick: true,
        displayOptions: {
          building: opts.showBuildings || mapStore.showBuildings,
          poi: true,
          poiText: true,
          indoor: true
        },
        minZoom: BAIDU_MAP_CONFIG.defaultOptions.minZoom,
        maxZoom: BAIDU_MAP_CONFIG.defaultOptions.maxZoom
      });
      
      // 设置地图中心点和缩放级别
      const centerPoint = new window.BMapGL.Point(
        opts.center.lng || mapStore.center.lng,
        opts.center.lat || mapStore.center.lat
      );
      map.value.centerAndZoom(centerPoint, opts.zoom || mapStore.zoom);
      
      // 配置地图选项
      map.value.enableScrollWheelZoom(BAIDU_MAP_CONFIG.defaultOptions.enableScrollWheelZoom);
      map.value.enableDragging(BAIDU_MAP_CONFIG.defaultOptions.enableDragging);
      map.value.enableDoubleClickZoom(BAIDU_MAP_CONFIG.defaultOptions.enableDoubleClickZoom);
      map.value.enableInertialDragging(BAIDU_MAP_CONFIG.defaultOptions.enableInertialDragging);
      map.value.enableContinuousZoom(BAIDU_MAP_CONFIG.defaultOptions.enableContinuousZoom);
      
      // 设置地图类型
      setMapType(opts.mapType || mapStore.mapType);
      
      // 添加控件
      if (opts.showControls) {
        addControls();
      }
      
      // 添加事件监听
      setupEventListeners();
      
      // 同步状态到store
      mapStore.setZoom(map.value.getZoom());
      const center = map.value.getCenter();
      mapStore.setCenter(center.lng, center.lat);
      mapStore.setMapType(opts.mapType as any);
      
      // 更新状态
      initialized.value = true;
      
      // 触发ready事件回调
      if (opts.onReady) {
        opts.onReady(map.value);
      }
      
      return true;
    } catch (err) {
      const e = err as Error;
      logger.error('地图初始化失败', e);
      error.value = e.message;
      return false;
    } finally {
      loading.value = false;
    }
  }
  
  /**
   * 设置地图类型
   */
  function setMapType(mapType: string): void {
    if (!map.value || !window.BMapGL) return;
    
    try {
      let mapTypeObj;
      switch (mapType) {
        case 'satellite':
          mapTypeObj = window.BMapGL.MapType.BMAP_SATELLITE_MAP;
          break;
        case 'hybrid':
          mapTypeObj = window.BMapGL.MapType.BMAP_HYBRID_MAP;
          break;
        default:
          mapTypeObj = window.BMapGL.MapType.BMAP_NORMAL_MAP;
      }
      map.value.setMapType(mapTypeObj);
      // 同步到store
      mapStore.setMapType(mapType as any);
    } catch (e) {
      logger.error('设置地图类型失败:', e);
    }
  }
  
  /**
   * 添加地图控件
   */
  function addControls(): void {
    if (!map.value || !window.BMapGL) return;
    
    try {
      // 添加比例尺控件
      if (opts.showScaleControl) {
        const scaleControl = new window.BMapGL.ScaleControl();
        map.value.addControl(scaleControl);
        controls.set('scale', scaleControl);
      }
      
      // 添加缩放控件
      if (opts.showZoomControl) {
        const zoomControl = new window.BMapGL.ZoomControl();
        map.value.addControl(zoomControl);
        controls.set('zoom', zoomControl);
      }
      
      // 添加地图类型控件
      if (opts.showMapTypeControl) {
        const mapTypeControl = new window.BMapGL.MapTypeControl();
        map.value.addControl(mapTypeControl);
        controls.set('mapType', mapTypeControl);
      }
      
      // 添加城市列表控件
      if (opts.showCityListControl) {
        const cityListControl = new window.BMapGL.CityListControl({
          // 保持默认的停靠位置（通常是左上角）
          anchor: window.BMapGL.ControlAnchor.TOP_LEFT,
          // 添加向右的偏移量，向右偏移100像素
          offset: new window.BMapGL.Size(400, 10)
        });
        map.value.addControl(cityListControl);
        controls.set('cityList', cityListControl);
      }
      
      // 添加定位控件
      if (opts.showLocationControl) {
        const locationControl = new window.BMapGL.LocationControl({
          // 设置控件停靠在右下角
          anchor: window.BMapGL.ControlAnchor.BOTTOM_RIGHT,
          // 偏移量：
          offset: new window.BMapGL.Size(10, 100)
        });
        map.value.addControl(locationControl);
        controls.set('location', locationControl);
      }
      
      // 添加3D控件
      if (opts.show3DControl) {
        const d3Control = new window.BMapGL.NavigationControl3D();
        map.value.addControl(d3Control);
        controls.set('3d', d3Control);
      }
    } catch (e) {
      logger.error('添加地图控件失败:', e);
    }
  }
  
  /**
   * 设置地图事件监听器
   */
  function setupEventListeners(): void {
    if (!map.value) return;
    
    try {
      // 地图点击事件
      const clickHandler = (e: any) => {
        if (opts.onClick) {
          opts.onClick({
            type: 'click',
            point: e.point,
            pixel: e.pixel,
            target: e.target
          });
        }
      };
      map.value.addEventListener('click', clickHandler);
      eventListeners.set('click', clickHandler);
      
      // 地图移动结束事件
      const moveEndHandler = (e: any) => {
        const zoom = map.value.getZoom();
        const center = map.value.getCenter();
        
        // 同步到store
        mapStore.setZoom(zoom);
        mapStore.setCenter(center.lng, center.lat);
        
        if (opts.onMoveEnd) {
          opts.onMoveEnd({
            type: 'move-end',
            zoom,
            center
          });
        }
      };
      map.value.addEventListener('moveend', moveEndHandler);
      eventListeners.set('moveend', moveEndHandler);
      
      // 地图缩放结束事件
      map.value.addEventListener('zoomend', moveEndHandler);
      eventListeners.set('zoomend', moveEndHandler);
    } catch (e) {
      logger.error('设置地图事件监听失败:', e);
    }
  }
  
  /**
   * 清除所有事件监听器
   */
  function clearEventListeners(): void {
    if (!map.value) return;
    
    try {
      eventListeners.forEach((handler: any, eventName: string) => {
        map.value.removeEventListener(eventName, handler);
      });
      
      eventListeners.clear();
    } catch (e) {
      logger.error('清除地图事件监听失败:', e);
    }
  }
  
  /**
   * 设置地图中心点
   */
  function setCenter(point: MapPoint): void {
    if (!map.value) return;
    
    try {
      const center = new window.BMapGL.Point(point.lng, point.lat);
      map.value.setCenter(center);
      
      // 同步到store
      mapStore.setCenter(point.lng, point.lat);
    } catch (e) {
      logger.error('设置地图中心点失败:', e);
    }
  }
  
  /**
   * 设置地图缩放级别
   */
  function setZoom(zoom: number): void {
    if (!map.value) return;
    
    try {
      map.value.setZoom(zoom);
      
      // 同步到store
      mapStore.setZoom(zoom);
    } catch (e) {
      logger.error('设置地图缩放级别失败:', e);
    }
  }
  
  /**
   * 地图适应视野
   */
  function fitMapBounds(points: MapPoint[]): void {
    if (!map.value || !points.length) return;
    
    try {
      const bounds = new window.BMapGL.Bounds();
      
      for (const point of points) {
        const bPoint = new window.BMapGL.Point(point.lng, point.lat);
        bounds.extend(bPoint);
      }
      
      map.value.setViewport(bounds, {
        enableAnimation: true,
        margins: [50, 50, 50, 50]
      });
      
      // 同步到store
      const center = map.value.getCenter();
      mapStore.setZoom(map.value.getZoom());
      mapStore.setCenter(center.lng, center.lat);
    } catch (e) {
      logger.error('设置地图视野失败:', e);
    }
  }
  
  /**
   * 重置地图
   */
  function resetMap(): void {
    if (!map.value) return;
    
    try {
      // 重置到默认中心点和缩放级别
      const center = new window.BMapGL.Point(
        BAIDU_MAP_CONFIG.defaultCenter.lng,
        BAIDU_MAP_CONFIG.defaultCenter.lat
      );
      map.value.centerAndZoom(center, BAIDU_MAP_CONFIG.defaultOptions.zoom);
      
      // 同步到store
      mapStore.setZoom(BAIDU_MAP_CONFIG.defaultOptions.zoom);
      mapStore.setCenter(
        BAIDU_MAP_CONFIG.defaultCenter.lng,
        BAIDU_MAP_CONFIG.defaultCenter.lat
      );
      
      if (opts.onReset) {
        opts.onReset();
      }
    } catch (e) {
      logger.error('重置地图失败:', e);
    }
  }
  
  /**
   * 处理重试加载地图
   */
  function handleRetry(): void {
    mapStore.loadMapOnDemand({
      forceReload: true,
      loadTrack: true
    }).then((success: boolean) => {
      if (success) {
        initMap();
      }
    }).catch((err: any) => {
      logger.error('重试加载地图失败:', err);
    });
  }
  
  /**
   * 清理资源
   */
  function cleanup(): void {
    // 清除事件监听器
    clearEventListeners();
    
    // 清除控件
    if (map.value) {
      controls.forEach((control: any) => {
        try {
          map.value.removeControl(control);
        } catch (e) {
          logger.error('移除地图控件失败:', e);
        }
      });
      
      // 清空集合
      controls.clear();
    }
    
    // 释放地图实例
    map.value = null;
    initialized.value = false;
  }
  
  // 组件挂载时初始化地图
  onMounted(() => {
    if (!opts.lazyLoad) {
      // 非懒加载模式，直接初始化地图
      initMap();
    } else {
      // 懒加载模式，不立即初始化，而是监听需要时才加载
      logger.info('地图采用懒加载模式，需要时再初始化');
      // 可选：预加载地图资源但不创建实例
      mapStore.loadMapOnDemand().then((success: boolean) => {
        if (success) {
          logger.info('地图资源预加载完成');
          // 注意：此处不调用initMap()，等待需要时再调用
        }
      });
    }
  });
  
  // 在组件卸载前清理资源
  onUnmounted(() => {
    cleanup();
  });
  
  // 返回公共API
  return {
    // 响应式状态
    mapContainerRef,
    map,
    initialized,
    loading,
    error,
    trackPluginLoaded,
    
    // 方法
    initMap,
    setCenter,
    setZoom,
    setMapType,
    fitMapBounds,
    resetMap,
    handleRetry,
    cleanup
  };
} 